package cn.crc.sysinfo;

import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.software.os.FileSystem;
import oshi.software.os.NetworkParams;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;

import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 读取机器信息_23.9.4-lhz
 */
public class SystemInfoUtil {

    private static SystemInfoDTO getSystemInfo() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        OperatingSystem os = si.getOperatingSystem();
        NetworkParams networkParams = os.getNetworkParams();

        SystemInfoDTO systemInfoDTO= new SystemInfoDTO();
        systemInfoDTO.setHost(networkParams.getHostName());
        systemInfoDTO.setDns(Arrays.toString(networkParams.getDnsServers()));
        systemInfoDTO.setGateway(networkParams.getIpv4DefaultGateway());

        GlobalMemory memory= hal.getMemory();
        systemInfoDTO.setMemTotal(FormatUtil.formatBytes(memory.getTotal()));
        systemInfoDTO.setMemFree(FormatUtil.formatBytes(memory.getAvailable()));

        List<NetworkIF> networkIFs= hal.getNetworkIFs();
        List<String[]> ipList= new ArrayList<String[]>();
        List<String> macList= new ArrayList<String>();
        for (NetworkIF net : networkIFs) {
            if(net.getIPv4addr()!=null&&net.getIPv4addr().length>0) {
                ipList.add(net.getIPv4addr());
                if(net.getMacaddr()!=null&&net.getMacaddr().length()>0)
                    macList.add(net.getMacaddr());
            }
        }
        if(ipList.size()==1) systemInfoDTO.setIp(ipList.get(0)[0]);
        if(macList.size()==1) systemInfoDTO.setMac(macList.get(0));

        InetAddress localHost = null;
        try {
            localHost = Inet4Address.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        NetworkInterface networkInterface = null;
        try {
            networkInterface = NetworkInterface.getByInetAddress(localHost);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
            if(systemInfoDTO.getIp()!=null&&address.getAddress().toString().contains(systemInfoDTO.getIp())&&systemInfoDTO.getNetmask()==null) {
                systemInfoDTO.setNetmask(calcMaskByPrefixLength(address.getNetworkPrefixLength()));
            }
        }

        List<String> diskList= new ArrayList<String>();
        FileSystem fileSystem= os.getFileSystem();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            long usable = fs.getUsableSpace();
            long total = fs.getTotalSpace();
            diskList.add(fs.getName()+fs.getDescription()+"["+fs.getType()+"] "+FormatUtil.formatBytes(usable)+" of "+FormatUtil.formatBytes(total)+" "+String.format("%.1f",100d*usable/total)+"%");
        }
        systemInfoDTO.setDiskList(diskList);
        return systemInfoDTO;
    }

    public static String calcMaskByPrefixLength(int length) {
        int mask = -1 << (32 - length);
        int partsNum = 4;
        int bitsOfPart = 8;
        int maskParts[] = new int[partsNum];
        int selector = 0x000000ff;
        for (int i = 0; i < maskParts.length; i++) {
            int pos = maskParts.length - 1 - i;
            maskParts[pos] = (mask >> (i * bitsOfPart)) & selector;
        }
        String result = "";
        result = result + maskParts[0];
        for (int i = 1; i < maskParts.length; i++) {
            result = result + "." + maskParts[i];
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getSystemInfo());
    }
}
